home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 4
/
QRZ Ham Radio Callsign Database - Volume 4.iso
/
files
/
dsp
/
56ktools
/
a5611.tz
/
a5611
/
examples
/
rvb2.asm
< prev
next >
Wrap
Assembly Source File
|
1992-08-11
|
20KB
|
416 lines
; filename: RVB2.ASM
;
;
; This code is an optimized version of the reverberation algorithm
; found in file RVB1.ASM. This program makes use of the parallel
; move functionality of the 56001. While this tends to make the
; code less readible, it does increase its speed. This version
; is intended to run on the DSP56000ADSx (Application Development
; System)board rev #2, with memory expansion. The memory should
; be configured figured for 8K p-memory, 16K x-memory, 8K y-memory.
;
; Further gains in algorithm speed could be realized on boards not
; constrained by the ADS memory limitations. For example, due to
; the need for 4 comb filters' worth of storage (each using about
; 3500 samples - which takes 4096 samples each after using the DSM
; statement) to fit into the 16K available for the x memory, we
; must start at address $0000. Thus, we are forced to use all the
; 56000's internal memory for sample storage. Without being forced
; to start sample storage at $0000, the 56000's internal memory could
; be used for coefficient storage, allowing better use of parallel
; x and y moves.
;
; Motorola DSP Group
; Austin, Texas
;
;**************************************************************************
; This program was originally available on the Motorola DSP bulletin board
; and is provided under a DISCLAIMER OF WARRANTY available from Motorola
; DSP Operation, 6501 William Cannon Dr. W Austin, Texas 78735-8598.
;**************************************************************************
;--------------------------------------------------------------------------
; This reverberation program is a variation of the reverberation
; system and structures as described by James Moorer's article entitled
; 'About this Reverberation Business', Computer Music Journal,
; 3(2):13-28, 1979
;
; Structure is:
; .----------.
; .------------. .-----. | All Pass |
; +->| Comb Filter|-->| SUM |-->| Reverb |
; Note: All Comb | | #1 | '-----' | |
; Filters | '------------' ^ ^ ^ '----------'
; Have a 1st | .------------. | | | |
; Order IIR |->| Comb Filter|---+ | | .---V---.
; LPF in their | | #2 | | | | align |
; feedback | '------------' | | | delay |
; loop | .------------. | | '---|---'
; |->| Comb Filter|------+ | |
; | | #3 | | ----- reverb
; | '------------' | \./ gain
; | .------------. | |
; |->| Comb Filter|---------+ |
; | | #4 | |
; | '------------' |
; | V
; .------------. | FIR gain .----------.
; | Early | | |\ | |
;input -->| Reflection |--+---------| >------------>| summer |--- output
; | | FIR | |/ | |
; | '------------' '----------'
; | ^
; | |
; | dry gain |
; | |\ |
; +------------------------------| >----------------+
; |/
;
;.............................................................................
; COMB FILTER SUB STRUCTURE:
; .-------.
; comb i .-----. | long | comb i
; input ------>| sum |---->| delay |-------+---------> output
; '-----' '-------' |
; ^ |
; | V
; | /| .-----.
; +-----< ------------| sum |<--------+
; \| '-----' |
; fdbck i | / \ lpf i gain
; gain V /_____\
; gain .----------. |
; | 1 sample | |
; | delay |-----+
; '----------'
;.............................................................................
; UNIT (ALL PASS) REVERBERATOR STRUCTURE:
; based on Schroeder as outlined in Griesinger: 'Practical Processors and
; Programs for Digital Reverberation', Audio in Digital Times, 7th AES
; conference, Toronto, Ontario, 1989
; (the structure outlined in Moorer is a variation of this)
;
; -g
; |\
; +---------->| >--------------------------+
; | |/ |
; | |
; | V
; unit | .-----. .--------. |\ .-----. unit
; input ------+--->| sum |-->| delay |--+--->| >-->| sum |-----> output
; '-----' '--------' | |/ '-----'
; ^ | 1-g**2
; | g |
; | /| |
; +-----< |---------+
; \|
;
;...........................................................................
;
; one multi-tap fir structure - to handle early reflections
;
; followed by 4 parallel comb (iir) filters (each comb having
; a first order LPF in its feedback loop
;
; followed by an 'allpass' reverberator whose output is then
; delayed so that its first output follows after the last "early
; reflection" output
;
;__________________________________________________________________________
;
opt cex
page 132
;--------------------------------------------------constant declarations
adc equ $ffef ; ADC address
dac equ $ffef ; DAC address
ntap equ 7 ; number of taps
ntapp10 equ ntap+10 ; # taps + 10 for other variables
tapmod equ ntapp10-1 ; number of taps minus 1
dlymx equ 4000 ; length of delay line in samples
cmbdly1 equ 2205 ; COMB FILTER CONSTANTS
cmbdly2 equ 2690 ; delay values (in samples)
cmbdly3 equ 3175
cmbdly4 equ 3440
cmbmod1 equ 3490 ; modulo for comb #1 delay line THESE ARE
cmbmod2 equ 3490 ; " " #2 " " ALSO THE
cmbmod3 equ 3490 ; " " #3 " " MAX DELAYS
cmbmod4 equ 3490 ; " " #4 " " ALLOWED FOR
; CHOSEN DSM
; VALUE
untrvbdly equ 265 ; delay UNIT (or ALLPASS)
unt_g equ 0.7 ; gains (g) REVERBERATOR
neg_g equ -unt_g ; (-g)
one_m_g2 equ (1-unt_g*unt_g) ; " (1-g**2)
cmb_g equ 0.86 ; (OVERALL) COMB FILTER FEEDBACK GAIN
; controls reverb decay time: smaller
; values give quicker decay, larger
; values yield slower decay
lpf1 equ 0.408 ; lpf filter coefficient in the
lpf2 equ 0.448 ; feedback loop of the combs,
lpf3 equ 0.476 ; these LPF's simulate the high freq
lpf4 equ 0.496 ; attentuation in real acoustic reverb
fdbck1 equ cmb_g*(1-lpf1) ; actual comb feedback gain
fdbck2 equ cmb_g*(1-lpf2) ; is determined by the lpf filter
fdbck3 equ cmb_g*(1-lpf3) ; coefficient and the overall feed-
fdbck4 equ cmb_g*(1-lpf4) ; back gain to insure stability
aligndly equ 1305 ; alignment delay (see diagram above)
alignmod equ 1390 ; " mod
reverbg equ 0.35 ; reverberation output gain value
firg equ 0.15 ; early rflctn FIR output gain value
dryg equ 0.9999-(reverbg+firg) ; dry signal gain is rest
; CHOOSE THE MIX YOU LIKE
org x:0
chead1 dsm 3500 ; allocates 3500 data spaces for use as
chead2 dsm 3500 ; comb filter tap delay lines, CHEAD1 refers
chead3 dsm 3500 ; to the Comb filter HEAD (beginning) for
chead4 dsm 3500 ; filter #1
org x:$0f00
ofst_bf dsm ntapp10 ; this reserves "ntap" contiguous addresses
org x:ofst_bf ; starting at the closest appropriate modulo
ofst0 dc 1 ; x address space. Then starts filling the
ofst1 dc 877 ; offset buffer at this location with
ofst2 dc 1561 ; the right delay values for the
ofst3 dc 1716 ; EARLY REFLECTION FIR
ofst4 dc 1826
ofst5 dc 3083 ; IMPORTANT - to get no delay for the first
ofst6 dc 3510 ; early reflection, use a "1". This is due the use
; of an instruction code pre-decrement, a "0" value
; will cause a maximum delay equal to the tap delay
; line length
untdly dc untrvbdly ; define the UNIT REVERBERATOR delay
untmod dc untrvbdly-1 ; modulo for " "
algndly dc aligndly
algnmod dc alignmod
org y:$0f00
gain_bf dsm ntapp10
org y:gain_bf ; starting at y address zero this reserves
; "ntap" contiguous addresses then starts
; filling these addresses with the desired
gain0 dc 0.213 ; tap "gain" values for EARLY REFLECTION FIR
gain1 dc 0.217 ; recommended by moorer
gain2 dc 0.174 ;
gain3 dc 0.135 ; it is recommended to keep many early
gain4 dc 0.153 ; reflection returns, as these are fed into
gain5 dc 0.157 ; comb filters, than can contribute greatly
gain6 dc 0.051 ; to the later impulse response density
c1g2 dc fdbck1
c2g2 dc fdbck2
c3g2 dc fdbck3
c4g2 dc fdbck4
c1out ds 1
untg2 dc neg_g
untg3 dc one_m_g2
untg1 dc unt_g
firgain dc firg
drygain dc dryg
rvbgain dc reverbg
org y:0
c1g1 dc lpf1 ; comb #1 g1 (LPF gain)
c2g1 dc lpf2 ; #2
c3g1 dc lpf3 ; #3
c4g1 dc lpf4 ; #4
sample ds 1 ; input sample storage address
firout ds 1 ; early ref FIR OUTput storage address
; COMB filter output storage address
c2out ds 1 ; " " #2 " " "
lpfst1 ds 1 ; " " #1 Low Pass Filter state
lpfst2 ds 1 ; " " #2 " " " "
lpfst3 ds 1 ; " " #3 " " " "
lpfst4 ds 1 ; " " #4 " " " "
; allocates modulo memory for the unit
udlyln dsm 300 ; (allpass) reverberator delay line
algndlyln dsm 1400 ; allocates modulo memory for alignment delay
; line
dlyline dsm dlymx ; allocates mod memory for the FIR delay line
;--------------------------------------------------------------------------
org p:$40 ; program start address
; Set up ADS board in case of force break instead of force reset
movep #0,x:$FFFE ;set bcr to zero
movec #0,sp ;init stack pointer
movec #0,sr ;clear loop flag
; Set up the SSI for operation with the DSP56ADC16EVB
; The following code sets port C to function as SCI/SSI
move #$0,a0 ;zero PCC to cycle it
movep a0,x:$FFE1
move #$0001ff,a0
movep a0,x:$FFE1 ;write PCC
; The following code sets the SSI CRA and CRB control registers for external
; continuous clock, synchronous, normal mode.
move #$004000,a0 ;CRA pattern for word length=16 bits
movep a0,x:$FFEC
move #$003200,a0 ;CRB pattern for continous ck,sych,normal mode
movep a0,x:$FFED ;word long frame sync: FSL=0;ext ck/fs
; -------------------------------------------------------------------------
; initialize registers MO,RO, etc
move #dlymx-1,m0 ; tap line modulus
move #dlyline,r0 ; start of delay line
move #0,n0 ;
move #tapmod,m1 ; tap gain line modulo
move #gain_bf,r1 ; tap gain & tap delay pointer
move #cmbmod1,m2 ; initialize the modulo registers
move #cmbmod2,m3 ; for comb filter buffers 1 thru 5
move #cmbmod3,m4
move #cmbmod4,m5
move #cmbdly1,n2 ; initialize the offset register
move #cmbdly2,n3 ; for Comb filters 1 thru 5
move #cmbdly3,n4
move #cmbdly4,n5
move #chead1,r2 ; initialize the pointer values for
move #chead2,r3 Comb filters 1 thru 5
move #chead3,r4
move #chead4,r5
move x:algnmod,m6 ; initialize alignment delay line
move x:algndly,n6 ; offset, modulo, and pointer registers
move #algndlyln,r6
move x:untmod,m7 ; initialize unit reverberator (allpass)
move x:untdly,n7 ; offset, modulo, and pointer registers
move #udlyln,r7
;---------------------------------------------------------------------------
; The following code polls the RDF flag in the SSI-SR and waits for RDF=1
; and then reads the RX register to retrieve the data from the A/D converter.
; Sample rate is controlled by DSP56ADC16 board.
poll jclr #7,x:$FFEE,poll ;loop until RDF bit = 1
movep x:adc,a ;get A/D converter data
;---------------------------------------------------------------------------
asr a
asr a ; obtain data sample
; and shift right for headroom
move a,y:sample ; keep dry sample
; - - - - - - - - - - - - - - - - - - - - - - - -
; FIR for early reflections
move a,y:(r0)- ; push sample into delay line
clr a x:(r1),n0 ; clr A and load offset into N0
do #ntap,fir ; loop over the (ntaps-1),exclude fb tap now
move y:(r1)+,y1 ; " " " gain " " Y
move y:(r0+n0),x1 ; get delayed sample
mac x1,y1,a x:(r1),n0 ; MAC gain and sample & update offset
fir move a,y:firout ; save FIR OUTput to y memory
; - - - - - - - - - - - - - - - - - - - - - - - -
; COMB 1
move x:(r2+n2),b ; get delayed sample & put in b
move b,y:c1out ; move output to y memory space
move y:c1g1,x1 ; get LPF filter coeff
move y:lpfst1,y1 ; get LPF filter state
mac x1,y1,b y:(r1)+,x1 ; compute LPF output
move b,y:lpfst1 ; save LPF output to LPF state
move b,y1 ; put LPF output in Y1
mac x1,y1,a x:(r3+n3),b ; compute feedback term in A
move a,x:(r2)- ; store output into delay queue
; - - - - - - - - - - - - - - - - - - - - - - - -
; COMB 2
move y:firout,a ; comb filter #1 with LPF in feed back
move b,y:c2out ; move output to y memory space
move y:c2g1,x1 ; get LPF filter coeff
move y:lpfst2,y1 ; get LPF filter state
mac x1,y1,b y:(r1)+,x1 ; compute LPF output
move b,y:lpfst2 ; save LPF output to LPF state
move b,y1 ; put LPF output in Y1
mac x1,y1,a x:(r4+n4),b ; compute feedback term in A
move a,x:(r3)- ; store output into delay queue
; - - - - - - - - - - - - - - - - - - - - - - - -
; COMB 3
move y:firout,a ; comb filter #1 with LPF in feed back
move b,x0
move y:c3g1,x1 ; get LPF filter coeff
move y:lpfst3,y1 ; get LPF filter state
mac x1,y1,b y:(r1)+,x1 ; compute LPF output
move b,y:lpfst3 ; save LPF output to LPF state
move b,y1 ; put LPF output in Y1
mac x1,y1,a x:(r5+n5),b ; compute feedback term in A
move a,x:(r4)- ; store output into delay queue
; - - - - - - - - - - - - - - - - -
; COMB 4
move y:firout,a ;
move b,y0
move y:c4g1,x1 ; get LPF filter coeff
move y:lpfst4,y1 ; get LPF filter state
mac x1,y1,b y:(r1)+,x1 ; compute LPF output
move b,y:lpfst4 ; save LPF output to LPF state
move b,y1 ; put LPF output in Y1
mac x1,y1,a y:(r1)+,x1 ; compute feedback term in A,c1out to x1
move a,x:(r5)- ; store output into delay queue
; - - - - - - - - - - - - - - - - - - - - - - - -
move y:c2out,a ; add output of add four combs
add x1,a ; c2out + c1out
add x0,a y:(r7+n7),x0 ; +c3out
add y0,a y:(r1)+,y1 ; +c4out
; asr a
; - - - - - - - - - - - - - - - - - -
; all pass unit reverberator
move a,x1
mpy x1,y1,b y:(r1)+,y1
mac x0,y1,b y:(r1)+,y1 ; MAC into b for output (B CONTAINS OUTPUT)
move b,y:(r6)-
mac x1,y1,a y:(r6+n6),y1
move a,y:(r7)- ; put new+g*delayed into delay line/inc r7
; - - - - - - - - - - - - -
move y:rvbgain,y0
mpy y1,y0,a y:(r1)+,x1
move y:firout,y1
mac x1,y1,a y:(r1)+,x1
move y:sample,y1 ; mix in the dry sample
mac x1,y1,a ; A now contains the output sample
asr a
; - - - - - - - - - - - - - - - - - - - - - - - -
; Write DSP56ADC16 A/D converter data to the PCM-56
move a,x:dac ;write the PCM-56 D/A via SSI xmt reg.
jmp poll ;loop indefinitely
end